﻿function replaceAll(originstring, toreplace, replacetext) {
    originstring = originstring.replace(toreplace, replacetext);
    if (originstring.indexOf(toreplace) > -1)
        return replaceAll(originstring, toreplace, replacetext);
    return originstring;
}

//motor
var orden;
var ordenClon;
var servicios = obtenerServicios();
var condiciones = obtenerCondiciones();
var beneficios = obtenerBeneficios();
var beneficiosPorCondiciones = obtenerBeneficiosPorCondiciones();
var expresiones = [];
var orderbeneficios;
var codes = [];
var cloneExpresiones = [];

function obtenerServicios() {
    var listaServicios = [];
    var servicio = new Object();
    servicio.servicioid = 1;
    servicio.subtipoid = null;
    servicio.descripcion = "Servicio A";
    servicio.preciobase = 85;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 1;
    servicio.subtipoid = 1;
    servicio.descripcion = "Subtipo A1";
    servicio.preciobase = 85;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 1;
    servicio.subtipoid = 2;
    servicio.descripcion = "Subtipo A2";
    servicio.preciobase = 50;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 1;
    servicio.subtipoid = 3;
    servicio.descripcion = "Subtipo A3";
    servicio.preciobase = 78;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 2;
    servicio.subtipoid = null;
    servicio.descripcion = "Servicio B";
    servicio.preciobase = 0;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 2;
    servicio.subtipoid = 1;
    servicio.descripcion = "Subtipo B1";
    servicio.preciobase = 100;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 2;
    servicio.subtipoid = 2;
    servicio.descripcion = "Subtipo B2";
    servicio.preciobase = 100;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 2;
    servicio.subtipoid = 3;
    servicio.descripcion = "Subtipo B3";
    servicio.preciobase = 120;
    listaServicios.push(servicio);

    servicio = new Object();
    servicio.servicioid = 3;
    servicio.descripcion = "service3";
    servicio.preciobase = 300;
    listaServicios.push(servicio);

    return listaServicios;
}

function obtenerServiciosPorId(id, subtipoid) {
    return $(servicios).filter(function (e, v) { return v.servicioid == id & v.subtipoid == subtipoid; })[0];
}

function obtenerCondiciones() {
    var listaCondiciones = [];
    var condicion = new Object();
    condicion.condicionid = 1;
    condicion.despuesCalculos = false;
    condicion.descripcion = "CantidadMinimaIndividual";
    condicion.expresion = "[cantidadServicio] >= [cantidadServicioCondicion]";
    listaCondiciones.push(condicion);

    condicion = new Object();
    condicion.condicionid = 2;
    condicion.despuesCalculos = false;
    condicion.descripcion = "MontoMinimoIndividual";
    condicion.expresion = "[montoServicio] >= [MontoServicioCondicion]";
    listaCondiciones.push(condicion);

    condicion = new Object();
    condicion.condicionid = 3;
    condicion.despuesCalculos = false;
    condicion.descripcion = "MontoMinimoTotal";
    condicion.expresion = "[montoTotalServicio] >= [MontoTotalServicioCondicion]";
    listaCondiciones.push(condicion);

    condicion = new Object();
    condicion.condicionid = 4;
    condicion.despuesCalculos = true;
    condicion.descripcion = "MontoTotalTransaccion";
    condicion.expresion = "[MontoTotalTransaccion] >= [MontoTotalTransaccionCondicion]";
    listaCondiciones.push(condicion);

    condicion = new Object();
    condicion.condicionid = 5;
    condicion.despuesCalculos = true;
    condicion.descripcion = "MedioPago";
    condicion.expresion = "[MedioPago] == [MedioPagoCondicion]";
    listaCondiciones.push(condicion);

    condicion = new Object();
    condicion.condicionid = 6;
    condicion.despuesCalculos = true;
    condicion.descripcion = "VariablePromocional";
    condicion.expresion = "[VariablePromocional] == [VariablePromocionalCondicion]";
    listaCondiciones.push(condicion);
    return listaCondiciones;
}

function obtenerCondicionPorId(id) {
    return $(condiciones).filter(function (e, v) { return v.condicionid == id; })[0];
}

function obtenerBeneficios() {
    var listaBeneficios = [];
    var beneficio = new Object();
    beneficio.beneficioid = 1;
    beneficio.descripcion = "montoDescuento";
    beneficio.expresion = "var beneficioMonto = [montoDescuento]; beneficio.montos.push(beneficioMonto); ";
    listaBeneficios.push(beneficio);

    beneficio = new Object();
    beneficio.beneficioid = 2;
    beneficio.descripcion = "porcentajeDescuento";
    beneficio.expresion = "var beneficioMonto = [montoTotalServicio]*[porcentajeDescuento]/100; beneficio.montos.push(beneficioMonto);";
    listaBeneficios.push(beneficio);

    beneficio = new Object();
    beneficio.beneficioid = 3;
    beneficio.descripcion = "porcentajeDescuentoTransaccion";
    beneficio.expresion = "var beneficioMonto = [MontoTotalTransaccion]*[porcentajeDescuento]/100; beneficio.montos.push(beneficioMonto);";
    listaBeneficios.push(beneficio);

    return listaBeneficios;
}

function obtenerBeneficioPorId(id) {
    return $(beneficios).filter(function (e, v) { return v.beneficioid == id; })[0];
}

function obtenerBeneficiosPorCondiciones() {
    var listaCondicionBeneficio = [];
    listaCondicionBeneficio.push(beneficioCondicion1());
    listaCondicionBeneficio.push(beneficioCondicion3());

    return listaCondicionBeneficio;
}

//prioridad - menor numero mayor prioridad
//tipo: 1: exclusiva; 2: no acumulable: 3: acumulable
//promocion para el servicio 1 subtipo 1 por cantidad
function beneficioCondicion1() {
    //service beneficio1
    var condicionBeneficio = new Object();
    condicionBeneficio.condicionBeneficioid = 1;
    condicionBeneficio.prioridad = 1;
    condicionBeneficio.tipo = 2;
    condicionBeneficio.montoMaximoDescuento = 200;
    condicionBeneficio.condiciones = [];

    //CONDICION1
    var condicion = new Object();
    condicion.subcondiciones = [];
    var subcondicion = new Object();
    subcondicion.condicionid = 1;
    subcondicion.listaServicios = [];
    var servicio = new Object();
    servicio.servicioid = 1;
    servicio.subtipoid = 1;
    subcondicion.listaServicios.push(servicio);
    subcondicion.parametros = [];
    var parametro = new Object();
    parametro.nombre = "variablepromocional";
    parametro.valor = 1;
    subcondicion.parametros.push(parametro);
    condicion.subcondiciones.push(subcondicion);

    condicionBeneficio.condiciones.push(condicion);

    condicionBeneficio.beneficios = [];
    var beneficio = new Object();
    beneficio.beneficioId = 2;
    beneficio.monto = 15;
    beneficio.inServicio = true;
    condicionBeneficio.beneficios.push(beneficio);
    beneficio = new Object();
    beneficio.beneficioId = 1;
    beneficio.monto = 150;
    beneficio.inServicio = true;
    condicionBeneficio.beneficios.push(beneficio);
    return condicionBeneficio;
}
//promocion para el servicio 2 por cantidad
function beneficioCondicion2() {
    //service beneficio2
    var condicionBeneficio = new Object();
    condicionBeneficio.condicionBeneficioid = 2;
    condicionBeneficio.prioridad = 1;
    condicionBeneficio.tipo = 2;
    condicionBeneficio.condiciones = [];

    //CONDICION2
    var condicion = new Object();
    condicion.subcondiciones = [];
    var subcondicion = new Object();
    subcondicion.condicionid = 1;
    subcondicion.listaServicios = [];
    var servicio = new Object();
    servicio.servicioid = 2;
    servicio.subtipoid = null;
    subcondicion.listaServicios.push(servicio);
    subcondicion.parametros = [];
    var parametro = new Object();
    parametro.nombre = "cantidad";
    parametro.valor = 1;
    subcondicion.parametros.push(parametro);
    condicion.subcondiciones.push(subcondicion);

    condicionBeneficio.condiciones.push(condicion);

    condicionBeneficio.beneficios = [];
    var beneficio = new Object();
    beneficio.beneficioId = 2;
    beneficio.monto = 15;
    beneficio.inServicio = true;
    condicionBeneficio.beneficios.push(beneficio);
    return condicionBeneficio;
}
//promocion para el servicio 1 o servicio 2 por cantidad
function beneficioCondicion3() {
    //service beneficio3
    var condicionBeneficio = new Object();
    condicionBeneficio.condicionBeneficioid = 3;
    condicionBeneficio.prioridad = 1;
    condicionBeneficio.tipo = 2;
    condicionBeneficio.montoMaximoDescuento = null;
    condicionBeneficio.condiciones = [];

    //CONDICION2
    var condicion = new Object();
    condicion.subcondiciones = [];
    var subcondicion = new Object();
    subcondicion.condicionid = 1;
    subcondicion.listaServicios = [];
    var servicio = new Object();
    servicio.servicioid = 1;
    servicio.subtipoid = null;
    subcondicion.listaServicios.push(servicio);
    servicio = new Object();
    servicio.servicioid = 2;
    servicio.subtipoid = null;
    subcondicion.listaServicios.push(servicio);
    subcondicion.parametros = [];
    var parametro = new Object();
    parametro.nombre = "cantidad";
    parametro.valor = 1;
    subcondicion.parametros.push(parametro);
    condicion.subcondiciones.push(subcondicion);

    condicionBeneficio.condiciones.push(condicion);

    condicionBeneficio.beneficios = [];
    var beneficio = new Object();
    beneficio.beneficioId = 2;
    beneficio.monto = 15;
    beneficio.inServicio = true;
    condicionBeneficio.beneficios.push(beneficio);
    return condicionBeneficio;
}

function obtenerOrden() {
    var orden = new Object();
    orden.servicios = [];
    orden.montoTotal = 0;
    orden.montoTotalPrevioDescuentos = 0;
    orden.montoTotalDescuentos = 0;
    orden.montoGravado = 0;
    orden.montoSubTotal = 0;
    orden.IGV = 0;
    orden.beneficios = [];
    orden.montoVisita = 10;
    orden.exonerarMontoVisita = false;
    orden.mediopago = "\"efectivo\"";
    orden.variablepromocional = "\"122\"";
    return orden;
}

function obtenerExpresion(orderbeneficios, servicio) {
    var evalexp;
    $(orderbeneficios).each(function (e, v) {
        evalexp = "if (";
        $(v.condiciones).each(function (e1, v1) {
            evalexp = evalexp + "(";
            $(v1.subcondiciones).each(function (e2, v2) {
                evalexp = evalexp + "(";
                var condicion = obtenerCondicionPorId(v2.condicionid);
                var code;
                //se compara la cantidad de cada servicio de la condicion
                //[cantidadServicio] >= [cantidadServicioCondicion]
                if (condicion.descripcion == "CantidadMinimaIndividual") {
                    var parametro = $(v2.parametros).filter(function (e3, v3) { return v3.nombre == "cantidad"; })[0];
                    $(v2.listaServicios).each(function (e3, v3) {
                        if (v3.subtipoid != null) {
                            evalexp = evalexp + condicion.expresion + " || ";
                            evalexp = evalexp.replace("[cantidadServicioCondicion]", parametro.valor.toString());
                            evalexp = evalexp.replace("[cantidadServicio]", "[cantidadServicio," + v3.servicioid.toString() + "," + v3.subtipoid.toString() + "]");
                            code = new Object();
                            code.initial = "[cantidadServicio]";
                            code.final = "[cantidadServicio," + v3.servicioid.toString() + "," + v3.subtipoid.toString() + "]";
                            code.servicioid = v3.servicioid;
                            code.subtipoid = v3.subtipoid;
                            code.condicion = condicion.descripcion;
                            if ($(codes).filter(function (e4, v4) { return v4.final == code.final; }).length == 0)
                                codes.push(code);
                        } else {
                            $(obtenerServicios())
                                .filter(function (e4, v4) { return v4.servicioid == v3.servicioid & v4.subtipoid != null; })
                                .each(function (e4, v4) {
                                    evalexp = evalexp + condicion.expresion + " || ";
                                    evalexp = evalexp.replace("[cantidadServicioCondicion]", parametro.valor.toString());
                                    evalexp = evalexp.replace("[cantidadServicio]", "[cantidadServicio," + v3.servicioid.toString() + "," + v4.subtipoid.toString() + "]");
                                    code = new Object();
                                    code.initial = "[cantidadServicio]";
                                    code.final = "[cantidadServicio," + v3.servicioid.toString() + "," + v4.subtipoid.toString() + "]";
                                    code.servicioid = v3.servicioid;
                                    code.subtipoid = v4.subtipoid;
                                    code.condicion = condicion.descripcion;
                                    if ($(codes).filter(function (e5, v5) { return v5.final == code.final; }).length == 0)
                                        codes.push(code);
                                });
                        }
                    });
                }

                //se compara el monto de cada servicio de la condicion
                //[montoServicio] >= [MontoServicioCondicion]
                if (condicion.descripcion == "MontoMinimoIndividual") {
                    var parametro = $(v2.parametros).filter(function (e3, v3) { return v3.nombre == "monto"; })[0];
                    $(v2.listaServicios).each(function (e3, v3) {
                        if (v3.subtipoid != null) {
                            evalexp = evalexp + condicion.expresion + " || ";
                            evalexp = evalexp.replace("[MontoServicioCondicion]", parametro.valor.toString());
                            evalexp = evalexp.replace("[montoServicio]", "[montoServicio," + v3.servicioid.toString() + "," + v3.subtipoid.toString() + "]");
                            code = new Object();
                            code.initial = "[montoServicio]";
                            code.final = "[montoServicio," + v3.servicioid.toString() + "," + v3.subtipoid.toString() + "]";
                            code.servicioid = v3.servicioid;
                            code.subtipoid = v3.subtipoid;
                            code.condicion = condicion.descripcion;
                            if ($(codes).filter(function (e4, v4) { return v4.final == code.final; }).length == 0)
                                codes.push(code);
                        } else {
                            $(obtenerServicios())
                                .filter(function (e4, v4) { return v4.servicioid == v3.servicioid & v4.subtipoid != null; })
                                .each(function (e4, v4) {
                                    evalexp = evalexp + condicion.expresion + " || ";
                                    evalexp = evalexp.replace("[MontoServicioCondicion]", parametro.valor.toString());
                                    evalexp = evalexp.replace("[montoServicio]", "[montoServicio," + v3.servicioid.toString() + "," + v4.subtipoid.toString() + "]");
                                    code = new Object();
                                    code.initial = "[montoServicio]";
                                    code.final = "[montoServicio," + v3.servicioid.toString() + "," + v4.subtipoid.toString() + "]";
                                    code.servicioid = v3.servicioid;
                                    code.subtipoid = v4.subtipoid;
                                    code.condicion = condicion.descripcion;
                                    if ($(codes).filter(function (e5, v5) { return v5.final == code.final; }).length == 0)
                                        codes.push(code);
                                });
                        }
                    });
                }

                //se compara el monto de la suma de todos los servicios de la condicion
                //[montoTotalServicio] >= [MontoTotalServicioCondicion]
                if (condicion.descripcion == "MontoMinimoTotal") {
                    evalexp = evalexp + condicion.expresion + " & ";
                    var parametro = $(v2.parametros).filter(function (e3, v3) { return v3.nombre == "monto"; })[0];
                    evalexp = evalexp.replace("[MontoTotalServicioCondicion]", parametro.valor.toString());
                    var exps = "";
                    $(v2.listaServicios).each(function (e3, v3) {
                        if (v3.subtipoid != null) {
                            code = new Object();
                            exps = exps + "[montoTotalServicio," + v3.servicioid.toString() + "," + v3.subtipoid.toString() + "] + ";
                            code.initial = "[montoTotalServicio]";
                            code.final = "[montoTotalServicio," + v3.servicioid.toString() + "," + v3.subtipoid.toString() + "]";
                            code.servicioid = v3.servicioid;
                            code.subtipoid = v3.subtipoid;
                            code.condicion = condicion.descripcion;
                            if ($(codes).filter(function (e4, v4) { return v4.final == code.final; }).length == 0)
                                codes.push(code);
                        } else {
                            $(obtenerServicios())
                                .filter(function (e4, v4) { return v4.servicioid == v3.servicioid & v4.subtipoid != null; })
                                .each(function (e4, v4) {
                                    code = new Object();
                                    exps = exps + "[montoTotalServicio," + v3.servicioid.toString() + "," + v4.subtipoid.toString() + "] + ";
                                    code.initial = "[montoTotalServicio]";
                                    code.final = "[montoTotalServicio," + v3.servicioid.toString() + "," + v4.subtipoid.toString() + "]";
                                    code.servicioid = v3.servicioid;
                                    code.subtipoid = v4.subtipoid;
                                    code.condicion = condicion.descripcion;
                                    if ($(codes).filter(function (e5, v5) { return v5.final == code.final; }).length == 0)
                                        codes.push(code);
                                });
                        }
                    });
                    evalexp = evalexp.replace("[montoTotalServicio]", exps.substring(0, exps.length - 2));
                }

                //se compara el monto total de la transaccion
                //[MontoTotalTransaccion] >= [MontoTotalTransaccionCondicion]
                if (condicion.descripcion == "MontoTotalTransaccion") {
                    evalexp = evalexp + condicion.expresion + "   ";
                    var parametro = $(v2.parametros).filter(function (e3, v3) { return v3.nombre == "monto"; })[0];
                    evalexp = evalexp.replace("[MontoTotalTransaccionCondicion]", parametro.valor.toString());
                }

                //se compara el medio de pago de la transaccion
                //[MedioPago] == [MedioPagoCondicion]
                if (condicion.descripcion == "MedioPago") {
                    evalexp = evalexp + condicion.expresion + "   ";
                    var parametro = $(v2.parametros).filter(function (e3, v3) { return v3.nombre == "mediopago"; })[0];
                    evalexp = evalexp.replace("[MedioPagoCondicion]", parametro.valor.toString());
                }

                //se compara la variable promocional del cliente de la transaccion
                //[VariablePromocional] == [VariablePromocionalCondicion]
                if (condicion.descripcion == "VariablePromocional") {
                    evalexp = evalexp + condicion.expresion + "   ";
                    var parametro = $(v2.parametros).filter(function (e3, v3) { return v3.nombre == "variablepromocional"; })[0];
                    evalexp = evalexp.replace("[VariablePromocionalCondicion]", parametro.valor.toString());
                }
                evalexp = evalexp.substring(0, evalexp.length - 3) + ") & ";
            });
            evalexp = evalexp.substring(0, evalexp.length - 3) + ") || ";
        });
        evalexp = evalexp.substring(0, evalexp.length - 3) + ") {";

        if (v.beneficios.length > 0) {
            var beneficioExpresion = "var beneficio = new Object(); beneficio.condicionBeneficioid = [condicionBeneficioid]; beneficio.montototal = 0; beneficio.montos = [];"
            $(v.beneficios).each(function (e1, v1) {
                var beneficio = obtenerBeneficioPorId(v1.beneficioId);
                beneficioExpresion = beneficioExpresion + beneficio.expresion;
                if (beneficio.descripcion == "montoDescuento") {
                    beneficioExpresion = beneficioExpresion.replace("[montoDescuento]", v1.monto.toString());
                }
                if (beneficio.descripcion == "porcentajeDescuento") {
                    beneficioExpresion = beneficioExpresion.replace("[porcentajeDescuento]", v1.monto.toString());
                    var exps = "(";
                    $(v.condiciones).each(function (e2, v2) {
                        $(v2.subcondiciones).each(function (e3, v3) {
                            $(v3.listaServicios).each(function (e4, v4) {
                                if (v4.subtipoid != null) {
                                    code = new Object();
                                    exps = exps + "[montoTotalServicio," + v4.servicioid.toString() + "," + v4.subtipoid.toString() + "] + ";
                                    code.initial = "[montoTotalServicio]";
                                    code.final = "[montoTotalServicio," + v4.servicioid.toString() + "," + v4.subtipoid.toString() + "]";
                                    code.servicioid = v4.servicioid;
                                    code.subtipoid = v4.subtipoid;
                                    code.condicion = "MontoMinimoIndividual";
                                    if ($(codes).filter(function (e4, v4) { return v4.final == code.final; }).length == 0)
                                        codes.push(code);
                                } else {
                                    $(obtenerServicios())
                                        .filter(function (e5, v5) { return v5.servicioid == v4.servicioid & v5.subtipoid != null; })
                                        .each(function (e5, v5) {
                                            code = new Object();
                                            exps = exps + "[montoTotalServicio," + v4.servicioid.toString() + "," + v5.subtipoid.toString() + "] + ";
                                            code.initial = "[montoTotalServicio]";
                                            code.final = "[montoTotalServicio," + v4.servicioid.toString() + "," + v5.subtipoid.toString() + "]";
                                            code.servicioid = v4.servicioid;
                                            code.subtipoid = v5.subtipoid;
                                            code.condicion = "MontoMinimoIndividual";
                                            if ($(codes).filter(function (e6, v6) { return v6.final == code.final; }).length == 0)
                                                codes.push(code);
                                        });
                                }
                            });
                        });
                    });
                    beneficioExpresion = beneficioExpresion.replace("[montoTotalServicio]", exps.substring(0, exps.length - 2) + ")");
                }
                if (beneficio.descripcion == "porcentajeDescuentoTransaccion") {
                    beneficioExpresion = beneficioExpresion.replace("[porcentajeDescuento]", v1.monto.toString());
                }

            });
            evalexp = evalexp + beneficioExpresion + "orden.beneficios.push(beneficio);";
        }
        evalexp = evalexp + "}";
        evalexp = evalexp.replace("[condicionBeneficioid]", v.condicionBeneficioid.toString());
    });
    return evalexp;
}

function correrMotor() {
    orden.montoTotal = 0;
    orden.montoTotalPrevioDescuentos = 0;
    orden.montoTotalDescuentos = 0;
    orden.montoGravado = 0;
    orden.montoSubTotal = 0;
    orden.IGV = 0;
    orden.beneficios = [];

    ordenClon = $.extend(true, {}, orden);
    ordenClon.servicios = [];

    if (!orden.exonerarMontoVisita)
        orden.montoTotalPrevioDescuentos = orden.montoVisita;
    //sumarizar las cantidades y crear un clon con los servicios agrupados;
    $(orden.servicios).each(function (e, v) {
        var servicio = obtenerServiciosPorId(v.servicioid, v.subtipoid);
        v.preciobase = servicio.preciobase;
        v.montoTotal = servicio.preciobase * v.cantidad;
        orden.montoTotalPrevioDescuentos = orden.montoTotalPrevioDescuentos + v.montoTotal;

        var servicioOrdenClon = $(ordenClon.servicios).filter(function (e1, v1) { return v1.servicioid == v.servicioid & v1.subtipoid == v.subtipoid; })[0];
        if (servicioOrdenClon != undefined) {
            servicioOrdenClon.cantidad = servicioOrdenClon.cantidad + v.cantidad;
            servicioOrdenClon.montoTotal = servicioOrdenClon.montoTotal + v.montoTotal;
        }
        else {
            servicioOrdenClon = $.extend(true, {}, v);
            ordenClon.servicios.push(servicioOrdenClon);
        }
    });

    expresiones = [];
    $(ordenClon.servicios).each(function (e, v) {
        orderbeneficios = $(beneficiosPorCondiciones).filter(function (e1, v1) {
            return $(v1.condiciones).filter(function (e2, v2) {
                return $(v2.subcondiciones).filter(function (e3, v3) {
                    if (v3.listaServicios.length > 0) {
                        return $(v3.listaServicios).filter(function (e4, v4) {
                            return v4.servicioid == v.servicioid & (v4.subtipoid != null ? v4.subtipoid == v.subtipoid : true);
                        }).length != 0;
                    } else {
                        return true;
                    }
                }).length != 0;
            }).length != 0;
        });

        $(orderbeneficios).each(function (e1, v1) {
            var expresion = new Object();
            expresion.condicionBeneficioid = v1.condicionBeneficioid;
            expresion.prioridad = v1.prioridad;
            expresion.tipo = v1.tipo;
            expresion.expresion = obtenerExpresion(v1, v);

            if ($(expresiones).filter(function (e2, v2) { return v2.condicionBeneficioid == v1.condicionBeneficioid; }).length == 0)
                //if (expresiones.indexOf(expresion) == -1)
                expresiones.push(expresion);
        });
    });
    reemplazarExpresiones();
    evalExps();
    calculoMontosFinales();
}

function evalExps() {
    orden.beneficios = [];
    $(cloneExpresiones).each(function (e, v) {
        eval(v.expresion);
    });
}

function reemplazarExpresiones() {
    cloneExpresiones = [];
    $(expresiones).each(function (e, v) {
        var exp = $.extend(true, {}, v);
        $(codes).each(function (e1, v1) {
            var servicio = $(ordenClon.servicios).filter(function (e2, v2) { return v2.servicioid == v1.servicioid & v2.subtipoid == v1.subtipoid; })[0];

            if (servicio != undefined) {
                if (v1.condicion == "CantidadMinimaIndividual") {
                    exp.expresion = replaceAll(exp.expresion, v1.final, servicio.cantidad);
                }
                if (v1.condicion == "MontoMinimoIndividual") {
                    exp.expresion = replaceAll(exp.expresion, v1.final, servicio.montoTotal);
                }
                if (v1.condicion == "MontoMinimoTotal") {
                    exp.expresion = replaceAll(exp.expresion, v1.final, servicio.montoTotal);
                }

            } else {
                exp.expresion = replaceAll(exp.expresion, v1.final, 0);
            }
        });

        exp.expresion = replaceAll(exp.expresion, "[MedioPago]", orden.mediopago);
        exp.expresion = replaceAll(exp.expresion, "[VariablePromocional]", orden.variablepromocional);
        exp.expresion = replaceAll(exp.expresion, "[MontoTotalTransaccion]", orden.montoTotalPrevioDescuentos);
        cloneExpresiones.push(exp);
    });
}

function calculoMontosFinales() {
    $(orden.beneficios).each(function (e, v) {
        var beneficioporcondicion = $(beneficiosPorCondiciones).filter(function (e1, v1) { return v1.condicionBeneficioid == v.condicionBeneficioid; })[0];
        $(v.montos).each(function (e1, v1) {
            if (beneficioporcondicion.montoMaximoDescuento == null) {
                v.montototal = v.montototal + v1;
            }
            else {
                if (v.montototal + v1 < beneficioporcondicion.montoMaximoDescuento) {
                    v.montototal = v.montototal + v1;
                }
                else {
                    v.montototal = beneficioporcondicion.montoMaximoDescuento;
                }
            }
        });
    });
    var montoExclusivo = 0;
    var prioridadExclusivo = null;
    var beneficiosPorCondicionExclusivos = $(orden.beneficios).filter(function (e, v) {
        return $(beneficiosPorCondiciones).filter(function (e1, v1) {
            return v1.condicionBeneficioid == v.condicionBeneficioid;
        })[0].tipo == 1;
    });

    if (beneficiosPorCondicionExclusivos.length > 0) {
        beneficiosPorCondicionExclusivos.each(function (e, v) {
            var beneficioporcondicion = $(beneficiosPorCondiciones).filter(function (e1, v1) { return v1.condicionBeneficioid == v.condicionBeneficioid; })[0];
            if (prioridadExclusivo == null) {
                prioridadExclusivo = beneficioporcondicion.prioridad;
            }
            if (prioridadExclusivo < beneficioporcondicion.prioridad) {
                montoExclusivo = v.montototal;
            }
            if (prioridadExclusivo = beneficioporcondicion.prioridad & v.montototal > montoExclusivo) {
                montoExclusivo = v.montototal;
            }
        });
    } else {
        $(orden.beneficios).filter(function (e, v) {
            return $(beneficiosPorCondiciones).filter(function (e1, v1) {
                return v1.condicionBeneficioid == v.condicionBeneficioid;
            })[0].tipo == 2;
        }).each(function (e, v) {
            var beneficioporcondicion = $(beneficiosPorCondiciones).filter(function (e1, v1) { return v1.condicionBeneficioid == v.condicionBeneficioid; })[0];
            if (prioridadExclusivo == null) {
                prioridadExclusivo = beneficioporcondicion.prioridad;
            }
            if (prioridadExclusivo < beneficioporcondicion.prioridad) {
                montoExclusivo = v.montototal;
            }
            if (prioridadExclusivo = beneficioporcondicion.prioridad & v.montototal > montoExclusivo) {
                montoExclusivo = v.montototal;
            }
        });
    }

    var montoAcumulado = 0;
    $(orden.beneficios).filter(function (e, v) {
        return $(beneficiosPorCondiciones).filter(function (e1, v1) {
            return v1.condicionBeneficioid == v.condicionBeneficioid;
        })[0].tipo == 3;
    }).each(function (e, v) {
        montoAcumulado = montoAcumulado + v.montototal;
    });
    orden.montoTotalDescuentos = montoAcumulado + montoExclusivo;
    orden.montoSubTotal = orden.montoTotalPrevioDescuentos - orden.montoTotalDescuentos;
    orden.montoGravado = orden.montoSubTotal / 1.18;
    orden.IGV = orden.montoSubTotal * 0.18 / 1.18;
    orden.montoTotal = orden.montoGravado + orden.IGV;
}

function inicio() {
    orden = obtenerOrden();
}

function agregarServicio(servicioid, subtipoid, cantidad) {
    var servicio = new Object();
    servicio.servicioid = servicioid;
    servicio.subtipoid = subtipoid;
    servicio.cantidad = cantidad;
    servicio.preciobase = null;

    orden.servicios.push(servicio);
    correrMotor();
}
inicio();